#![cfg(test)]

use nacos_cluster::{
    ClusterConfig, ClusterManager, DataSyncManager, ClusterConfigManager,
    ConfigChangeType, ConfigType,
};
use std::sync::Arc;

/// 测试配置管理器初始化
#[tokio::test]
async fn test_config_manager_initialization() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    let result = config_manager.initialize().await;
    assert!(result.is_ok());

    // 验证默认配置已加载
    let heartbeat = config_manager.get_config("heartbeat.interval").await.unwrap();
    assert_eq!(heartbeat, Some("5000".to_string()));
}

/// 测试配置设置和获取
#[tokio::test]
async fn test_config_set_and_get() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 测试设置配置
    config_manager.set_config(
        "test.config".to_string(),
        "test_value".to_string(),
        Some("Test configuration item".to_string()),
        "test_user".to_string(),
    ).await.unwrap();

    // 测试获取配置
    let value = config_manager.get_config("test.config").await.unwrap();
    assert_eq!(value, Some("test_value".to_string()));

    // 测试获取配置详情
    let details = config_manager.get_config_details("test.config").await.unwrap();
    assert!(details.is_some());
    let details = details.unwrap();
    assert_eq!(details.key, "test.config");
    assert_eq!(details.value, "test_value");
    assert_eq!(details.description, "Test configuration item");
    assert_eq!(details.config_type, ConfigType::String);
}

/// 测试配置类型猜测
#[tokio::test]
async fn test_config_type_guessing() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 测试整数类型
    config_manager.set_config(
        "test.integer".to_string(),
        "123".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    let details = config_manager.get_config_details("test.integer").await.unwrap();
    assert_eq!(details.unwrap().config_type, ConfigType::Integer);

    // 测试布尔类型
    config_manager.set_config(
        "test.boolean".to_string(),
        "true".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    let details = config_manager.get_config_details("test.boolean").await.unwrap();
    assert_eq!(details.unwrap().config_type, ConfigType::Boolean);

    // 测试JSON类型
    config_manager.set_config(
        "test.json".to_string(),
        '{"key": "value"}'.to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    let details = config_manager.get_config_details("test.json").await.unwrap();
    assert_eq!(details.unwrap().config_type, ConfigType::Json);
}

/// 测试配置验证
#[tokio::test]
async fn test_config_validation() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 测试有效配置
    let result = config_manager.set_config(
        "heartbeat.interval".to_string(),
        "3000".to_string(),
        None,
        "test".to_string(),
    ).await;
    assert!(result.is_ok());

    // 测试无效整数
    let result = config_manager.set_config(
        "heartbeat.interval".to_string(),
        "abc".to_string(),
        None,
        "test".to_string(),
    ).await;
    assert!(result.is_err());

    // 测试超出范围
    let result = config_manager.set_config(
        "heartbeat.interval".to_string(),
        "999".to_string(),
        None,
        "test".to_string(),
    ).await;
    assert!(result.is_err());

    let result = config_manager.set_config(
        "heartbeat.interval".to_string(),
        "60001".to_string(),
        None,
        "test".to_string(),
    ).await;
    assert!(result.is_err());
}

/// 测试配置删除
#[tokio::test]
async fn test_config_deletion() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 设置配置
    config_manager.set_config(
        "delete.test".to_string(),
        "delete_value".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    // 验证配置存在
    let value = config_manager.get_config("delete.test").await.unwrap();
    assert_eq!(value, Some("delete_value".to_string()));

    // 删除配置
    let result = config_manager.delete_config("delete.test", "test".to_string()).await;
    assert!(result.is_ok());

    // 验证配置已删除
    let value = config_manager.get_config("delete.test").await.unwrap();
    assert_eq!(value, None);
}

/// 测试获取所有配置
#[tokio::test]
async fn test_get_all_config() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 设置多个配置
    config_manager.set_config(
        "config1".to_string(),
        "value1".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    config_manager.set_config(
        "config2".to_string(),
        "value2".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    // 获取所有配置
    let all_config = config_manager.get_all_config().await.unwrap();
    
    assert!(all_config.contains_key("config1"));
    assert!(all_config.contains_key("config2"));
    assert!(all_config.contains_key("heartbeat.interval"));
    
    assert_eq!(all_config.get("config1"), Some(&"value1".to_string()));
    assert_eq!(all_config.get("config2"), Some(&"value2".to_string()));
}

/// 测试配置快照
#[tokio::test]
async fn test_config_snapshot() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 设置一些配置
    config_manager.set_config(
        "snapshot.test1".to_string(),
        "value1".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    config_manager.set_config(
        "snapshot.test2".to_string(),
        "value2".to_string(),
        None,
        "test".to_string(),
    ).await.unwrap();

    // 获取快照
    let snapshot = config_manager.get_config_snapshot().await.unwrap();
    
    assert!(snapshot.config_count >= 2);
    assert!(snapshot.local_config_count >= 2);
    assert!(snapshot.configs.contains_key("snapshot.test1"));
    assert!(snapshot.configs.contains_key("snapshot.test2"));
    assert!(snapshot.config_hash > 0);
}

/// 测试批量配置更新
#[tokio::test]
async fn test_batch_config_update() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 批量更新配置
    let configs = vec![
        ("batch1".to_string(), "value1".to_string(), Some("desc1".to_string())),
        ("batch2".to_string(), "value2".to_string(), Some("desc2".to_string())),
        ("batch3".to_string(), "value3".to_string(), None),
    ];

    let results = config_manager.batch_update_config(
        configs,
        "batch_user".to_string(),
    ).await.unwrap();

    assert_eq!(results.len(), 3);
    assert!(results.iter().all(|r| r.is_ok()));

    // 验证配置已设置
    assert_eq!(config_manager.get_config("batch1").await.unwrap(), Some("value1".to_string()));
    assert_eq!(config_manager.get_config("batch2").await.unwrap(), Some("value2".to_string()));
    assert_eq!(config_manager.get_config("batch3").await.unwrap(), Some("value3".to_string()));
}

/// 测试内置配置保护
#[tokio::test]
async fn test_builtin_config_protection() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 测试删除内置配置
    let result = config_manager.delete_config("cluster.name", "test".to_string()).await;
    assert!(result.is_err());

    // 测试修改内置配置
    let result = config_manager.set_config(
        "cluster.name".to_string(),
        "new_name".to_string(),
        None,
        "test".to_string(),
    ).await;
    assert!(result.is_ok()); // 应该允许修改
}

/// 测试动态配置识别
#[tokio::test]
async fn test_dynamic_config_detection() {
    let config = ClusterConfig::default();
    let cluster_manager = Arc::new(ClusterManager::new(config));
    let data_sync_manager = Arc::new(DataSyncManager::new(
        cluster_manager.clone(),
        3,
        100,
    ));

    let config_manager = ClusterConfigManager::new(
        cluster_manager,
        data_sync_manager,
    );

    config_manager.initialize().await.unwrap();

    // 测试动态配置
    let details = config_manager.get_config_details("heartbeat.interval").await.unwrap();
    assert!(details.is_some());
    assert!(details.unwrap().dynamic);

    // 测试非动态配置
    let details = config_manager.get_config_details("election.timeout").await.unwrap();
    assert!(details.is_some());
    assert!(!details.unwrap().dynamic);
}